package main

import (
	"fmt"
	"net"
	"net/http"
	"os"
	"strings"
	"time"

	"github.com/gin-contrib/cors"
	"github.com/gin-gonic/gin"
)

var configManager *ConfigManager

// IPInfo 存储 IP 地址及其来源信息
type IPInfo struct {
	Address string
	Source  string
}

// getLocalIPs 获取本机所有 IP 地址，仅用于调试信息
func getLocalIPs() []IPInfo {
	var ips []IPInfo

	// 添加 localhost
	ips = append(ips, IPInfo{
		Address: "localhost",
		Source:  "Local",
	})

	// 仅在调试模式下获取其他 IP
	if gin.Mode() == gin.DebugMode {
		addrs, err := net.InterfaceAddrs()
		if err != nil {
			return ips
		}

		for _, addr := range addrs {
			if ipnet, ok := addr.(*net.IPNet); ok && !ipnet.IP.IsLoopback() {
				if ip4 := ipnet.IP.To4(); ip4 != nil {
					// 只添加局域网 IP（192.168.x.x 或 10.x.x.x）
					ipStr := ip4.String()
					if strings.HasPrefix(ipStr, "192.168.") || strings.HasPrefix(ipStr, "10.") {
						ips = append(ips, IPInfo{
							Address: ipStr,
							Source:  "LAN",
						})
					}
				}
			}
		}
	}

	return ips
}

func main() {
	// 初始化配置管理器
	var err error
	configManager, err = NewConfigManager()
	if err != nil {
		fmt.Printf("Failed to initialize config manager: %v\n", err)
		os.Exit(1)
	}

	// 设置为发布模式
	gin.SetMode(gin.ReleaseMode)

	r := gin.Default()

	// 添加详细的日志中间件
	r.Use(func(c *gin.Context) {
		start := time.Now()
		fmt.Printf("Request: %s %s from %s\n",
			c.Request.Method,
			c.Request.URL.Path,
			c.ClientIP(),
		)
		c.Next()
		fmt.Printf("Response: %d %s latency: %v\n",
			c.Writer.Status(),
			c.Request.URL.Path,
			time.Since(start),
		)
	})

	// 获取本地 IP 列表用于 CORS 配置
	allowOrigins := []string{"http://localhost:8000"}
	// ipInfos := getLocalIPs()
	// for _, info := range ipInfos {
	// 	allowOrigins = append(allowOrigins, "http://"+info.Address+":8000")
	// }

	// 配置 CORS 中间件
	r.Use(cors.New(cors.Config{
		AllowOrigins: allowOrigins,                                        // 只允许特定的源
		AllowMethods: []string{"GET", "POST", "PUT", "DELETE", "OPTIONS"}, // 允许的 HTTP 方法
		AllowHeaders: []string{
			"Origin",
			"Content-Type",
			"Accept",
			"Authorization",
			"publisher-name", // 添加自定义请求头
			"serving-name-en",
			"api-key",
		},
		ExposeHeaders:    []string{"Content-Length", "Content-Type"},
		AllowCredentials: true,
		MaxAge:           12 * time.Hour, // 使用更合理的预检请求缓存时间
	}))

	// 提供静态文件服务
	staticPath := GetStaticPath()
	fmt.Printf("Serving static files from: %s\n", staticPath)
	r.Static("/static", staticPath)

	// 将根路径重定向到静态HTML页面
	r.GET("/", func(c *gin.Context) {
		c.Redirect(301, "/static/index.html")
	})

	// API 路由组 v1
	api := r.Group("/api")
	v1 := api.Group("/v1")
	{
		v1.POST("/chat/completions", handleChatCompletions)
		v1.GET("/apps", handleListModels)
		v1.GET("/apps/:namespace/:name", handleGetModelConfig)
	}

	// 获取端口配置，默认使用8000
	port := os.Getenv("PORT")
	if port == "" {
		port = "8000"
	}

	// 获取并显示所有可访问的地址
	fmt.Printf("Server is running on port %s\n", port)

	// 在调试模式下显示额外的 IP 地址
	if gin.Mode() == gin.DebugMode {
		ipInfos := getLocalIPs()
		for _, info := range ipInfos {
			if info.Source == "LAN" {
				fmt.Printf("  http://%s:%s\n", info.Address, port)
			}
		}
	}

	// 启动服务器配置
	s := &http.Server{
		Addr:           "0.0.0.0:" + port,
		Handler:        r,
		ReadTimeout:    30 * time.Second, // 增加超时时间
		WriteTimeout:   30 * time.Second,
		IdleTimeout:    120 * time.Second, // 添加空闲超时
		MaxHeaderBytes: 1 << 20,
	}

	if err := s.ListenAndServe(); err != nil {
		fmt.Printf("Failed to start server: %v\n", err)
		os.Exit(1)
	}
}

func handleChatCompletions(c *gin.Context) {
	var req ChatCompletionRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		c.JSON(400, gin.H{"error": err.Error()})
		return
	}

	// 从请求头获取模型信息
	namespace := c.GetHeader("publisher-name")
	modelName := c.GetHeader("serving-name-en")
	apiKey := c.GetHeader("api-key")

	// 构建转发到 WiseModel 的请求
	wiseResp, err := forwardToWiseModel(namespace, modelName, apiKey, &req)
	if err != nil {
		c.JSON(500, gin.H{"error": err.Error()})
		return
	}

	c.JSON(200, wiseResp)
}

func handleListModels(c *gin.Context) {
	// 使用 configManager 获取应用列表
	if configManager == nil {
		c.JSON(500, gin.H{"error": "Config manager not initialized"})
		return
	}

	// 直接返回 configManager 中的应用列表
	c.JSON(200, configManager.appList)
}

func handleGetModelConfig(c *gin.Context) {
	namespace := c.Param("namespace")
	name := c.Param("name")
	configType := c.Query("type") // 获取查询参数 type

	// 添加日志以便调试
	fmt.Printf("Requesting config: namespace=%s, name=%s, type=%s\n", namespace, name, configType)

	config, exists := configManager.GetAppConfig(namespace, name, configType)
	if !exists {
		c.JSON(404, gin.H{"error": "Model not found"})
		return
	}

	c.JSON(200, config)
}
